package br.com.fogas.utils;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;

public class FogasBoletoUtility {
	
	public String mascaraLinhaDigitavelBoleto(String linhaDigitavel) {
		//23792368019000037421638000512400263410000196500
		//23792.36801 90000.374216 38000.512400 2 63410000196500
		String temp = StringUtils.EMPTY;
		temp += StringUtils.substring(linhaDigitavel, 0, 5) + ".";//23792
		temp += StringUtils.substring(linhaDigitavel, 5, 10) + " ";//36801
		temp += StringUtils.substring(linhaDigitavel, 10, 15) + ".";//90000
		temp += StringUtils.substring(linhaDigitavel, 15, 21) + " ";//374216
		temp += StringUtils.substring(linhaDigitavel, 21, 26) + ".";//38000
		temp += StringUtils.substring(linhaDigitavel, 26, 32) + " ";//512400
		temp += StringUtils.substring(linhaDigitavel, 32, 33) + " ";//2
		temp += StringUtils.substring(linhaDigitavel, 33, linhaDigitavel.length());
		return temp;
	}
	
	public double valorMoraBoleto(double valorBoleto, double jurosAno) {
		jurosAno = valorArredondado(jurosAno).doubleValue();
		//double mora = ((juros ao ano / 360) * valorBoleto) / 100;
        double mora = ((jurosAno / 360) * valorBoleto) / 100;
		return valorArredondado(mora).doubleValue();
	}
	
	public double valorDescontoBoleto(double valorBoleto) {
		//desconto = valorBoleto * (-1);
        //ZFD3 se tiver
        double desconto = valorBoleto * (-1);
		return valorArredondado(desconto).doubleValue();
	}
	
	public BigDecimal valorArredondado(double valor) {
		BigDecimal total = new BigDecimal(valor);
		total = total.setScale(2, BigDecimal.ROUND_HALF_UP);
		return total;
	}
	
	public String geraNossoNumero(String serie, String nfNum, String org, boolean completo) {
		String zeros = "";
		org = StringUtils.substring(org, 0, 1);
		
		serie = StringUtils.leftPad(serie, 2, "0");

		int end = 11 - (org.length() + serie.length() + nfNum.length());
		for (int i = 1; i <= end; i++) {
			zeros += "0";
		}

		if (completo) {
			String nossoNumero = "09" + zeros + nfNum + org + serie;
			return nossoNumero + geraDVNossoNumero(nossoNumero);
		} else {
			return zeros + nfNum + org + serie;
		}
	}

	private String geraDVNossoNumero(String nossoNumero) {

		int calc = (2 * Integer.valueOf(String.valueOf(nossoNumero.toCharArray()[0])))
				+ (7 * Integer.valueOf(String.valueOf(nossoNumero.toCharArray()[1])))
				+ (6 * Integer.valueOf(String.valueOf(nossoNumero.toCharArray()[2])))
				+ (5 * Integer.valueOf(String.valueOf(nossoNumero.toCharArray()[3])))
				+ (4 * Integer.valueOf(String.valueOf(nossoNumero.toCharArray()[4])))
				+ (3 * Integer.valueOf(String.valueOf(nossoNumero.toCharArray()[5])))
				+ (2 * Integer.valueOf(String.valueOf(nossoNumero.toCharArray()[6])))
				+ (7 * Integer.valueOf(String.valueOf(nossoNumero.toCharArray()[7])))
				+ (6 * Integer.valueOf(String.valueOf(nossoNumero.toCharArray()[8])))
				+ (5 * Integer.valueOf(String.valueOf(nossoNumero.toCharArray()[9])))
				+ (4 * Integer.valueOf(String.valueOf(nossoNumero.toCharArray()[10])))
				+ (3 * Integer.valueOf(String.valueOf(nossoNumero.toCharArray()[11])))
				+ (2 * Integer.valueOf(String.valueOf(nossoNumero.toCharArray()[12])));

		calc = (11 - (calc - ((calc / 11) * 11)));
		String dig;
		if (calc == 10) {
			dig = "P";
		} else if (calc == 11) {
			dig = "0";
		} else {
			dig = String.valueOf(calc);
		}
		return dig;
	}
	
	public String geraNumeroBoleto(String serie, String nfNum, String orgVendas, Date vencimento, double vlrNota) {
        String nossoNumero = geraNossoNumero(serie, nfNum, orgVendas, false);
        String fatorVenc = fatorVencimentoBoleto(vencimento);
        String vlNominal = valorNominal(vlrNota);
        String parte = "2379" + fatorVenc + vlNominal + "236809" + nossoNumero + "00051240";
        String barra = insereDigitoCodBarra(parte);
        parte = StringUtils.substring(barra, 0, 4) + StringUtils.substring(barra, 19, 19+5);
        String linhaDig = parte + calculaCodigoDigito(parte);
        parte = barra.substring(24, 24+10);
        linhaDig += parte + calculaCodigoDigito(parte);
        parte = barra.substring(34, 34+10);      
        linhaDig += parte + calculaCodigoDigito(parte);
        parte = barra.substring(4, 4+15);
        linhaDig += parte;
        return linhaDig;
    }
	
	private static String fatorVencimentoBoleto(Date vencimento) {
		try {
			DateFormat format = new SimpleDateFormat("dd/MM/yyyy");
			Date dataBase = format.parse("07/10/1997");
			
			long diff = (vencimento.getTime() - dataBase.getTime());
			long diffDays = diff / (24 * 60 * 60 * 1000);
			
			return String.valueOf(diffDays);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
	
	private static String valorNominal(double vlrNota) {
		String vlrAux = FogasUtility.string.currencyFormat(vlrNota);
		
		vlrAux = StringUtils.replace(vlrAux, "R$", "").trim();
		vlrAux = StringUtils.replace(vlrAux, ".", "").trim();
		vlrAux = StringUtils.replace(vlrAux, ",", "").trim();
		
		String nominal = StringUtils.leftPad(vlrAux, 10, "0");
		return nominal;
	}
	
	private String insereDigitoCodBarra(String barra) {
        int soma = 0;
        int peso = 2;
        for (int i = barra.length() - 1; i >= 0; i--) {
            soma += (peso * Integer.valueOf(String.valueOf(barra.toCharArray()[i])));
            peso++;
            if (peso == 10) {
                peso = 2;
            }
        }
        int digito = 11 - (soma - (soma / 11) * 11);
        if (digito == 0 || digito > 9) {
            digito = 1;
        }
        String n1 = barra.substring(0, 4);
        String n2 = String.valueOf(digito);
        String n3 = barra.substring(4, 4+39);
        String n4 = n1 + n2 + n3;
        return n4;
    }

    private String calculaCodigoDigito(String codigo) {
        int soma = 0;
        int peso = 2;
        for (int i = codigo.length() - 1; i >= 0; i--) {
        	
            int calculo = peso * Integer.valueOf(String.valueOf(codigo.toCharArray()[i]));
            if (calculo >= 10) {
                calculo = Integer.valueOf(String.valueOf(String.valueOf(calculo).toCharArray()[0])) +
                		   Integer.valueOf(String.valueOf(String.valueOf(calculo).toCharArray()[1]));
            }
            soma += calculo;
            if (peso == 1) {
                peso = 2;
            } else {
                peso = 1;
            }
        }
        int digito = 10 - (soma - (soma / 10) * 10);
        if (digito == 10) {
            digito = 0;
        }
        return String.valueOf(digito);
    }
}
